/*
 * parallelYoung.h
 *
 *  Created on: May 29, 2013
 *      Author: sjelic
 */

#ifndef PARALLELYOUNG_H_
#define PARALLELYOUNG_H_

#include "coveringPackingLP.h"
#include "coveringPackingMiscellaneous.h"
texture<matrix_type, 2, cudaReadModeElementType> tex;

namespace mpcm{
	class ComputingStructures
	{
		public:
			int r;
			int c;
			int N; // in original implementation there is const N
			char sep;
			int countITERATIONS;

			//initializing CPU side
			real *x; // primal variables
			real *x_hat; // dual variables
			real  *y; // LHS in primal constraint y=Ax
			real *y_hat; // LHS in dual constraint y_hat=A^Tx_hat
			real *p;
			real *p_hat;
			int *imin;
			real beta1;

			//initializing GPU side
			real *dev_x;
			real *dev_x_hat;
			real *dev_y;
			real *dev_y_hat;
			real *dev_delta_y;
			real *dev_delta_y_hat;
			real *dev_p;
			real *dev_p_hat;
			real *dev_alpha_y;
			real *dev_alpha_y_hat;
			real *dev_beta1;
			real *dev_min;
			real *dev_Max;
			real *dev_alpha_matrix;
			real *dev_alpha;
			int *dev_countAlphaMin;
			int *dev_jmin;
			int *dev_imin;

			bool *keepOnRunning;
			bool *dev_keepOnRunning;

			bool *condition8;
			bool *dev_condition8;



			ComputingStructures(int, int, real);
			void initializeComputingStrucuters();
			~ComputingStructures();
	};

	class PerformanceStructures
	{
		public:
			real prim_obj;
			real dual_obj;
			float normalizationTime;
			float changeOfLHSTime;
			float alphaComputationTime;
			float updateOfPrimalDualTime;
			float scalePrimalDualTime;

			PerformanceStructures();
			real getPrimalDualGap();
			float totalComputationTime();
			~PerformanceStructures();

	};






	class ParallelYoung
	{
		public:

			real eps;
			PackingLinearProgram *myPackingLinearProgram;
			ComputingStructures *myComputingStructures;
			PerformanceStructures *myPerformanceStructures;

			ParallelYoung();
			void cpuScalingSolutions();
			void gpuScalingSolutions();
			~ParallelYoung();
	};



	class ParallelYoungDerandomized : public ParallelYoung
	{
		public:

			ParallelYoungDerandomized(real,string,float,bool);
			void optimizeInstance(real);
			void writingResultsToFileOnlyTimes(string, string, float, char);

			~ParallelYoungDerandomized();
	};

}




#endif /* PARALLELYOUNG_H_ */
